package xcmg.device.service.ratingManager;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.ratingManager.*;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.ratingManager.*;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.vo.ratingManager.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2019/7/12.
 */
@Service
public class ScoreInfoDetailService {
    @Autowired
    private ScoreInfoDOMapper scoreInfoDOMapper;
    @Autowired
    private SalesCompleteDetailDOMapper salesCompleteDetailDOMapper;
    @Autowired
    private MonthPlanAccuracyDetailDOMapper monthPlanAccuracyDetailDOMapper;
    @Autowired
    private OrderNormativeDetailDOMapper orderNormativeDetailDOMapper;
    @Autowired
    private OverallCompleteDetailDOMapper overallCompleteDetailDOMapper;
    @Autowired
    private ReceivableOverdueDetailMapper receivableOverdueDetailMapper;
    @Autowired
    private StockBusinessDetailDOMapper stockBusinessDetailDOMapper;
    @Autowired
    private CompanyDealerMapper companyDealerMapper;
    @Autowired
    private  AccountOverdueConfigService accountOverdueConfigService;
    //获取销售完成情况详情信息
    public List<SalesCompleteDetailVO> getSalesCompleteDetail(String scoreInfoId) {
        List<SalesCompleteDetailVO> voList = new ArrayList<>();
        List<SalesCompleteDetailDO> doList = salesCompleteDetailDOMapper.selectByScoreInfoId(scoreInfoId);
        for (SalesCompleteDetailDO salesCompleteDetailDO : doList) {
            SalesCompleteDetailVO vo = new SalesCompleteDetailVO();
            BeanUtils.copyProperties(salesCompleteDetailDO, vo);
            Integer score = vo.getScore();
            if (null == score){
                vo.setScore(0);
            }
            voList.add(vo);
        }
        return voList;
    }

    //月度计划准确性详情信息
    public MonthPlanAccuracyDetailVO getMonthPlanAccuracyDetail(String scoreInfoId) {
        MonthPlanAccuracyDetailDO monthPlanAccuracyDetailDO = monthPlanAccuracyDetailDOMapper.selectByScoreInfoId(scoreInfoId);
        MonthPlanAccuracyDetailVO vo = null;
        if (null != monthPlanAccuracyDetailDO) {
            vo = new MonthPlanAccuracyDetailVO();
            BeanUtils.copyProperties(monthPlanAccuracyDetailDO, vo);
        }
        return vo;
    }

    //订单管理规范性详情信息
    public OrderNormativeDetailVO getOrderNormativeDetail(String scoreInfoId) {
        OrderNormativeDetailDO orderNormativeDetailDO = orderNormativeDetailDOMapper.selectByScoreInfoId(scoreInfoId);
        OrderNormativeDetailVO vo = null;
        if (null != orderNormativeDetailDO) {
            vo = new OrderNormativeDetailVO();
            BeanUtils.copyProperties(orderNormativeDetailDO, vo);
        }
        return vo;
    }

    //应收账款逾期详情信息
    public ReceivableOverdueDetailVO getReceivableOverdueDetail(String scoreInfoId) {
        ReceivableOverdueDetailDO receivableOverdueDetailDO = receivableOverdueDetailMapper.selectByScoreInfoId(scoreInfoId);
        ReceivableOverdueDetailVO vo = null;
        if (null != receivableOverdueDetailDO) {
            vo = new ReceivableOverdueDetailVO();
            BeanUtils.copyProperties(receivableOverdueDetailDO, vo);
        }
        return vo;
    }

    //总体销售完成率详情信息
    public OverallCompleteDetailVO getOverallCompleteDetail(String scoreInfoId) {
        OverallCompleteDetailDO overallCompleteDetailDO = overallCompleteDetailDOMapper.selectByScoreInfoId(scoreInfoId);
        OverallCompleteDetailVO vo = null;
        if (null != overallCompleteDetailDO) {
            vo = new OverallCompleteDetailVO();
            BeanUtils.copyProperties(overallCompleteDetailDO, vo);
        }
        return vo;
    }

    //库存管理及业务规范性加减分详情信息
    public StockBusinessDetailVO getStockBusinessDetail(String scoreInfoId) {
        StockBusinessDetailDO stockBusinessDetailDO = stockBusinessDetailDOMapper.selectByScoreInfoId(scoreInfoId);
        StockBusinessDetailVO vo = null;
        if (null != stockBusinessDetailDO) {
            vo = new StockBusinessDetailVO();
            BeanUtils.copyProperties(stockBusinessDetailDO, vo);
        }
        return vo;
    }

    //修改获取销售完成情况详情信息
    public ErrorCode updateSalesCompleteDetail(List<SalesCompleteDetailVO> voList) throws Exception {
        Integer oldTotalScore = 0;
        Integer newTotalScore = 0;
        String scoreInfoId = null;

        for (SalesCompleteDetailVO salesCompleteDetailVO : voList) {
            if (StringUtils.isBlank(salesCompleteDetailVO.getId())) {
                throw new Exception(ErrorCode.IllegalArument.getDesc());
            }

            SalesCompleteDetailDO completeDetailDO = salesCompleteDetailDOMapper.selectByPrimaryKey(salesCompleteDetailVO.getId());
            oldTotalScore = oldTotalScore + (completeDetailDO.getScore() == null ? 0 : completeDetailDO.getScore());
            scoreInfoId = completeDetailDO.getScoreInfoId();

            SalesCompleteDetailDO updateCompleteDetailDO = new SalesCompleteDetailDO();
            BeanUtils.copyProperties(salesCompleteDetailVO, updateCompleteDetailDO);
            BigDecimal actualSalesAmount = salesCompleteDetailVO.getActualSalesAmount() == null ? BigDecimal.ZERO : salesCompleteDetailVO.getActualSalesAmount();
            BigDecimal salesTargetAmount = salesCompleteDetailVO.getSalesTargetAmount() == null ? BigDecimal.ZERO : salesCompleteDetailVO.getSalesTargetAmount();
            BigDecimal completeRate = BigDecimal.ZERO;
            if (salesTargetAmount.compareTo(BigDecimal.ZERO) != 0) {
                completeRate = (actualSalesAmount.divide(salesTargetAmount, 4, BigDecimal.ROUND_HALF_DOWN))
                        .multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
            }

            updateCompleteDetailDO.setCompleteRate(completeRate + "%");
            setCompleteDetailScore(updateCompleteDetailDO, completeRate);

            newTotalScore = newTotalScore + updateCompleteDetailDO.getScore();

            int updateCount = salesCompleteDetailDOMapper.updateByPrimaryKeySelective(updateCompleteDetailDO);
            if (updateCount <= 0) {
                throw new Exception("修改评分失败");
            }
        }

        if (StringUtils.isBlank(scoreInfoId)) {
            return ErrorCode.Failure;
        }

        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(scoreInfoId);
        Integer salesCompletion = scoreInfoDO.getSalesCompletion() == null ? 0 : scoreInfoDO.getSalesCompletion();
        int newSalesCompletion = (salesCompletion - oldTotalScore) + newTotalScore;

        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        scoreInfoDO.setTotalScore((totalScore - salesCompletion) + newSalesCompletion);

        scoreInfoDO.setSalesCompletion(newSalesCompletion);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }

    private void setCompleteDetailScore(SalesCompleteDetailDO completeDetailDO, BigDecimal completeRate) {
        completeDetailDO.setScore(4);
        if (completeRate.compareTo(new BigDecimal(100)) > 0) {
            completeDetailDO.setScore(10);
            return;
        }
        if (completeRate.compareTo(new BigDecimal(100)) <= 0 && completeRate.compareTo(new BigDecimal(90)) > 0) {
            completeDetailDO.setScore(8);
            return;
        }
        if (completeRate.compareTo(new BigDecimal(90)) <= 0 && completeRate.compareTo(new BigDecimal(80)) > 0) {
            completeDetailDO.setScore(6);
        }
    }

    //修改月度计划准确性详情信息
    public ErrorCode updateMonthPlanAccuracyDetail(MonthPlanAccuracyDetailVO vo) throws Exception {
        if (StringUtils.isBlank(vo.getId())) {
            return ErrorCode.IllegalArument;
        }
        MonthPlanAccuracyDetailDO detailDO = new MonthPlanAccuracyDetailDO();
        BeanUtils.copyProperties(vo, detailDO);
        BigDecimal monthOrder = new BigDecimal(detailDO.getMonthOrder());
        BigDecimal urgentOrder = new BigDecimal(detailDO.getUrgentOrder());
        BigDecimal totalOrder = monthOrder.add(urgentOrder);
        BigDecimal accuracyRate;
        if (totalOrder.compareTo(BigDecimal.ZERO) == 0){
             accuracyRate = BigDecimal.ZERO;
        }else {
             accuracyRate = monthOrder.divide(monthOrder.add(urgentOrder),4,BigDecimal.ROUND_HALF_DOWN).
                     multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
        }
        detailDO.setAccuracyRate(accuracyRate + "%");
        //计算得分
        setMonthPlanAccuracyDetailScore(accuracyRate, detailDO);

        int updateCount = monthPlanAccuracyDetailDOMapper.updateByPrimaryKeySelective(detailDO);
        if (updateCount <= 0) {
            throw new Exception("修改评分失败");
        }

        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(detailDO.getScoreInfoId());
        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        Integer monthPlanAccuracy = scoreInfoDO.getMonthPlanAccuracy()== null ? 0 : scoreInfoDO.getMonthPlanAccuracy();
        Integer score = detailDO.getScore() == null ? 0 : detailDO.getScore();
        scoreInfoDO.setTotalScore((totalScore - monthPlanAccuracy) + score);
        scoreInfoDO.setMonthPlanAccuracy(score);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }

    private void setMonthPlanAccuracyDetailScore(BigDecimal accuracyRate, MonthPlanAccuracyDetailDO record) {
        if (accuracyRate.compareTo(new BigDecimal(80)) > 0) {
            record.setScore(10);
            return;
        }
        if (accuracyRate.compareTo(new BigDecimal(70)) <= 0) {
            record.setScore(0);
            return;
        }

        for (int i = 0; i < 10; i++) {
            if (accuracyRate.compareTo(new BigDecimal(80 - i)) <= 0 && accuracyRate.compareTo(new BigDecimal(79 - i)) > 0) {
                record.setScore(9 - i);
                break;
            }
        }
    }

    //修改订单管理规范性详情信息
    public ErrorCode updateOrderNormativeDetail(OrderNormativeDetailVO vo) throws Exception {
        if (StringUtils.isBlank(vo.getId())) {
            return ErrorCode.IllegalArument;
        }
        OrderNormativeDetailDO detailDO = new OrderNormativeDetailDO();
        BeanUtils.copyProperties(vo, detailDO);
        long beyondQty = detailDO.getUrgentOrder() - detailDO.getAssessmentCriteria();
        if (beyondQty <= 0) {
            detailDO.setScore(10);
        } else {
            detailDO.setScore((int) (10 - (beyondQty * 2)));
        }

        if (detailDO.getScore() < 0) {
            detailDO.setScore(0);
        }

        int updateCount = orderNormativeDetailDOMapper.updateByPrimaryKeySelective(detailDO);
        if (updateCount <= 0) {
            throw new Exception("修改评分失败");
        }

        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(detailDO.getScoreInfoId());
        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        Integer orderManagerNormative = scoreInfoDO.getOrderManagerNormative()== null ? 0 : scoreInfoDO.getOrderManagerNormative();
        Integer score = detailDO.getScore() == null ? 0 : detailDO.getScore();
        scoreInfoDO.setTotalScore((totalScore - orderManagerNormative) + score);
        scoreInfoDO.setOrderManagerNormative(score);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }

    //修改应收账款逾期详情信息
    public ErrorCode updateReceivableOverdueDetail(ReceivableOverdueDetailVO vo) throws Exception {
        if (StringUtils.isBlank(vo.getId())) {
            return ErrorCode.IllegalArument;
        }
        ReceivableOverdueDetailDO detailDO = new ReceivableOverdueDetailDO();
        BeanUtils.copyProperties(vo, detailDO);
        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(detailDO.getScoreInfoId());

        BigDecimal customerQuota = BigDecimal.ZERO;
        CompanyDealerDO companyDealerDO = companyDealerMapper.item(Long.valueOf(scoreInfoDO.getClientId()));
        if (null != companyDealerDO){
            customerQuota = companyDealerDO.getTotalLimit().subtract(
                    companyDealerDO.getUsedLimit() == null ? BigDecimal.ZERO : companyDealerDO.getUsedLimit());
        }

        AccountOverdueConfigDO record = new AccountOverdueConfigDO();
        BeanUtils.copyProperties(detailDO,record);
        BigDecimal decimalScore = accountOverdueConfigService.getScore(record, customerQuota);

        detailDO.setScore(decimalScore.intValue());
        int updateCount = receivableOverdueDetailMapper.updateByPrimaryKeySelective(detailDO);
        if (updateCount <= 0) {
            throw new Exception("修改评分失败");
        }


        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        Integer accountsOverdue = scoreInfoDO.getAccountsOverdue()== null ? 0 : scoreInfoDO.getAccountsOverdue();
        Integer score = detailDO.getScore() == null ? 0 : detailDO.getScore();
        scoreInfoDO.setTotalScore((totalScore - accountsOverdue) + score);
        scoreInfoDO.setAccountsOverdue(score);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }

    //修改总体销售完成率详情信息
    public ErrorCode updateOverallCompleteDetail(OverallCompleteDetailVO vo) throws Exception {
        if (StringUtils.isBlank(vo.getId())) {
            return ErrorCode.IllegalArument;
        }
        OverallCompleteDetailDO detailDO = new OverallCompleteDetailDO();
        BeanUtils.copyProperties(vo, detailDO);
        BigDecimal targetAmount = detailDO.getTargetAmount();
        BigDecimal completeRate = BigDecimal.ZERO;
        if (null != targetAmount && targetAmount.compareTo(BigDecimal.ZERO) != 0){
             completeRate = (detailDO.getActualAmount().divide(detailDO.getTargetAmount(), 4, BigDecimal.ROUND_HALF_DOWN))
                    .multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
        }

        detailDO.setCompleteRate(completeRate + "%");
        setOverallCompleteDetailScore(detailDO, completeRate);
        int updateCount = overallCompleteDetailDOMapper.updateByPrimaryKeySelective(detailDO);
        if (updateCount <= 0) {
            throw new Exception("修改评分失败");
        }

        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(detailDO.getScoreInfoId());
        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        Integer salesCompletionRate = scoreInfoDO.getSalesCompletionRate()== null ? 0 : scoreInfoDO.getSalesCompletionRate();
        Integer score = detailDO.getScore() == null ? 0 : detailDO.getScore();
        scoreInfoDO.setTotalScore((totalScore - salesCompletionRate) + score);
        scoreInfoDO.setSalesCompletionRate(score);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }

    private void setOverallCompleteDetailScore(OverallCompleteDetailDO record, BigDecimal completeRate) {
        record.setScore(0);
        if (completeRate.compareTo(new BigDecimal(140)) > 0) {
            record.setScore(10);
            return;
        }
        for (int i = 0; i < 3; i++) {
            if (completeRate.compareTo(new BigDecimal(140 - i * 10)) <= 0 && completeRate.compareTo(new BigDecimal(130 - i * 10)) > 0) {
                record.setScore(8 - i * 2);
                break;
            }
        }
    }

    //修改库存管理及业务规范性加减分详情信息
    public ErrorCode updateStockBusinessDetail(StockBusinessDetailVO vo) throws Exception {
        if (StringUtils.isBlank(vo.getId())) {
            return ErrorCode.IllegalArument;
        }
        StockBusinessDetailDO detailDO = new StockBusinessDetailDO();
        BeanUtils.copyProperties(vo, detailDO);
        detailDO.setScore(detailDO.getCriterionScore() + detailDO.getStockScore());
        int updateCount = stockBusinessDetailDOMapper.updateByPrimaryKeySelective(detailDO);
        if (updateCount <= 0) {
            throw new Exception("修改评分失败");
        }

        ScoreInfoDO scoreInfoDO = scoreInfoDOMapper.selectByPrimaryKey(detailDO.getScoreInfoId());
        Integer totalScore = scoreInfoDO.getTotalScore() == null ? 0 : scoreInfoDO.getTotalScore();
        Integer inventoryBusiness = scoreInfoDO.getInventoryBusiness()== null ? 0 : scoreInfoDO.getInventoryBusiness();
        Integer score = detailDO.getScore() == null ? 0 : detailDO.getScore();
        scoreInfoDO.setTotalScore((totalScore - inventoryBusiness) + score);
        scoreInfoDO.setInventoryBusiness(score);
        int updateScoreInfoCount = scoreInfoDOMapper.updateByPrimaryKeySelective(scoreInfoDO);
        if (updateScoreInfoCount <= 0) {
            throw new Exception("修改评分失败");
        }

        return ErrorCode.Success;
    }
}
